package com.wander.nio.chat.nio;

import javax.management.MBeanServerConnection;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

public class NioChatServer {
    public static void main(String[] args) {
        try {
            Selector selector = Selector.open();
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
            serverSocketChannel.bind(new InetSocketAddress(8888));
            serverSocketChannel.configureBlocking(false);
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
            //循环监听客户端登入和可读事件
            while (true) {
                selector.select();
                Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                while (iterator.hasNext()) {
                    SelectionKey key = iterator.next();
                    iterator.remove();
                    if (key.isAcceptable()) {
                        handleAccept(selector, key);
                    } else if (key.isReadable()) {
                        handleRead(selector, key);
                    }
                }
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private static void handleAccept(Selector selector, SelectionKey key) throws IOException {
        //从服务端key获取客户端
        ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
        SocketChannel client = serverSocketChannel.accept();
        client.configureBlocking(false);
        client.register(selector, SelectionKey.OP_READ);
        System.out.println("新客户端建立连接：" + client.getRemoteAddress());
    }

    private static void handleRead(Selector selector, SelectionKey key) throws IOException {
        //客户端可读取事件，获取通道，通过buffer读取数据
        SocketChannel client = (SocketChannel) key.channel();
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        int read = client.read(buffer);
        if (read == -1) {
            key.cancel();
            client.close();
            System.out.println(client.getRemoteAddress() +  "客户端已下线");
        }
        buffer.flip();
        String msg = new String(buffer.array(),0,buffer.limit()).trim();
        System.out.println("收到客户端消息：" + msg);
    }
}
